﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OrBitDataModule.Adaptor
{
    public class DelayedSerialPort
    {
        public SerialPort SerialPort { get; private set; }
        private int delayMilliseconds = 0;

        public event EventHandler<byte[]> DataReceived;

        public int BaudRate
        {
            get { return SerialPort.BaudRate; }
            set { SerialPort.BaudRate = value; }
        }

        public bool IsOpen
        {
            get { return SerialPort.IsOpen; }
        }

        public int DelayMilliseconds
        {
            get { return delayMilliseconds; }
            set { delayMilliseconds = value; }
        }
        public string PortName { get => SerialPort.PortName; set => SerialPort.PortName = value; }

        public Parity Parity { get => SerialPort.Parity; set => SerialPort.Parity = value; }
        public int DataBits { get => SerialPort.DataBits; set => SerialPort.DataBits = value; }

        public StopBits StopBits { get => SerialPort.StopBits; set => SerialPort.StopBits = value; }

        public int ReadBufferSize { get => SerialPort.ReadBufferSize; set => SerialPort.ReadBufferSize = value; }

        public DelayedSerialPort()
        {
            SerialPort = new SerialPort
            {
                ReadBufferSize = 2 * 1024 * 1024 // 2M
            };
            SerialPort.DataReceived += SerialPort_DataReceived;
        }
        public DelayedSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
        {
            SerialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits)
            {
                ReadBufferSize = 2 * 1024 * 1024 // 2M
            };
            SerialPort.DataReceived += SerialPort_DataReceived;
        }

        public void Open()
        {
            if (!SerialPort.IsOpen)
            {
                SerialPort.Open();
            }
        }

        public void Close()
        {
            if (SerialPort.IsOpen)
            {
                Thread.Sleep(100);
                SerialPort.Close();
            }
        }

        public void Write(byte[] data)
        {
            SerialPort.Write(data, 0, data.Length);
        }

        private async void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            await Task.Delay(delayMilliseconds); // 延迟接收

            byte[] buffer = new byte[SerialPort.BytesToRead];
            SerialPort.Read(buffer, 0, buffer.Length);

            OnDataReceived(buffer);
        }

        protected virtual void OnDataReceived(byte[] data)
        {
            DataReceived?.Invoke(this, data);
        }
    }
}
